home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianSnap.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  14KB  |  703 lines

  1. /*ScianSnap.c
  2.   Eric Pepke
  3.   14 January 1993
  4.  
  5.   Routines for variable snapshots in SciAn
  6. */
  7.  
  8. #include "Scian.h"
  9. #include "ScianTypes.h"
  10. #include "ScianIDs.h"
  11. #include "ScianLists.h"
  12. #include "ScianArrays.h"
  13. #include "ScianErrors.h"
  14. #include "ScianSnap.h"
  15. #include "ScianWindows.h"
  16. #include "ScianObjWindows.h"
  17. #include "ScianControls.h"
  18. #include "ScianSymbols.h"
  19. #include "ScianGarbageMan.h"
  20. #include "ScianMethods.h"
  21. #include "ScianDatabase.h"
  22. #include "ScianDepend.h"
  23. #include "ScianTextFiles.h"
  24. #include "ScianScripts.h"
  25.  
  26. ObjPtr snapshotClass;            /*Class for all snapshots*/
  27.  
  28. #ifdef PROTO
  29. void AddSnapVar(ObjPtr object, NameTyp var)
  30. #else
  31. void AddSnapVar(object, var)
  32. ObjPtr object;
  33. NameTyp var;
  34. #endif
  35. /*Adds a snap var to object*/
  36. {
  37.     ObjPtr snapVars;
  38.  
  39.     snapVars = Get1Var(object, SNAPVARS);
  40.  
  41.     if (!snapVars)
  42.     {
  43.     snapVars = NewList();
  44.     }
  45.  
  46.     PostfixList(snapVars, NewSymbol(var));
  47.     SetVar(object, SNAPVARS, snapVars);
  48. }
  49.  
  50. #ifdef PROTO
  51. ObjPtr AssembleSnapVars(ObjPtr object)
  52. #else
  53. ObjPtr AssembleSnapVars(object)
  54. ObjPtr object;
  55. #endif
  56. /*Assembles some snap vars from object, superclass first*/
  57. {
  58.     if (object)
  59.     {
  60.         ObjPtr retVal;
  61.     ObjPtr curSnapVars;
  62.     ThingListPtr runner;
  63.  
  64.     retVal = AssembleSnapVars(ClassOf(object));
  65.     curSnapVars = Get1Var(object, SNAPVARS);
  66.     if (curSnapVars && IsList(curSnapVars))
  67.     {
  68.         if (!retVal)
  69.         {
  70.         retVal = NewList();
  71.         }
  72.         for (runner = LISTOF(curSnapVars); runner; runner = runner -> next)
  73.         {
  74.         if (WhichListIndex(retVal, runner -> thing) < 0)
  75.         {
  76.             PostfixList(retVal, runner -> thing);
  77.         }
  78.         }
  79.     }
  80.     return retVal;
  81.     }
  82.     else
  83.     {
  84.     return NULLOBJ;
  85.     }
  86. }
  87.  
  88. #ifdef PROTO
  89. ObjPtr TakeSnapshot(ObjPtr object)
  90. #else
  91. ObjPtr TakeSnapshot(object)
  92. ObjPtr object;
  93. #endif
  94. /*Takes a snapshot of object*/
  95. {
  96.     ObjPtr list;
  97.     ObjPtr retVal;
  98.  
  99.     /*Make the snap vars*/
  100.     list = AssembleSnapVars(object);
  101.  
  102.     retVal = NewObject(snapshotClass, 0L);
  103.     SetVar(retVal, REPOBJ, object);
  104.     SetVar(retVal, SNAPVARS, list);
  105.     if (list)
  106.     {
  107.     ThingListPtr runner;
  108.  
  109.     runner = LISTOF(list);
  110.     while (runner)
  111.     {
  112.         NameTyp id;
  113.  
  114.         id = GetSymbolID(runner -> thing);
  115.         if (id)
  116.         {
  117.         MakeVar(object, id);
  118.         SetVar(retVal, id, GetVar(object, id));
  119.         }
  120.         runner = runner -> next;
  121.     }
  122.     }
  123.     SetVar(retVal, NAME, GetVar(object, NAME));
  124.     SetVar(retVal, REPCLASSID, GetVar(object, CLASSID));
  125.  
  126.     return retVal;
  127. }
  128.  
  129. #ifdef PROTO
  130. ObjPtr TakeVarsSnapshot(ObjPtr object, ObjPtr list)
  131. #else
  132. ObjPtr TakeVarsSnapshot(object)
  133. ObjPtr object;
  134. #endif
  135. /*Takes a snapshot of object, the variables in list.*/
  136. {
  137.     ObjPtr retVal;
  138.  
  139.     retVal = NewObject(snapshotClass, 0L);
  140.     SetVar(retVal, REPOBJ, object);
  141.     SetVar(retVal, SNAPVARS, list);
  142.     if (list)
  143.     {
  144.     ThingListPtr runner;
  145.  
  146.     runner = LISTOF(list);
  147.     while (runner)
  148.     {
  149.         NameTyp id;
  150.  
  151.         id = GetSymbolID(runner -> thing);
  152.         if (id)
  153.         {
  154.         MakeVar(object, id);
  155.         SetVar(retVal, id, GetVar(object, id));
  156.         }
  157.         runner = runner -> next;
  158.     }
  159.     }
  160.     SetVar(retVal, NAME, GetVar(object, NAME));
  161.     SetVar(retVal, REPCLASSID, GetVar(object, CLASSID));
  162.  
  163.     return retVal;
  164. }
  165.  
  166. #ifdef PROTO
  167. ObjPtr TakeSingleVarSnapshot(ObjPtr object, NameTyp whichVar)
  168. #else
  169. ObjPtr TakeSingleVarSnapshot(object, whichVar)
  170. ObjPtr object;
  171. NameTyp whichVar;
  172. #endif
  173. /*Takes a snapshot of object*/
  174. {
  175.     ObjPtr list;
  176.     ObjPtr retVal;
  177.  
  178.     /*Make the snap vars*/
  179.     list = NewList();
  180.     PostfixList(list, NewSymbol(whichVar));
  181.  
  182.     retVal = NewObject(snapshotClass, 0L);
  183.     SetVar(retVal, REPOBJ, object);
  184.     SetVar(retVal, SNAPVARS, list);
  185.     if (list)
  186.     {
  187.     ThingListPtr runner;
  188.  
  189.     runner = LISTOF(list);
  190.     while (runner)
  191.     {
  192.         NameTyp id;
  193.  
  194.         id = GetSymbolID(runner -> thing);
  195.         if (id)
  196.         {
  197.         MakeVar(object, id);
  198.         SetVar(retVal, id, GetVar(object, id));
  199.         }
  200.         runner = runner -> next;
  201.     }
  202.     }
  203.     SetVar(retVal, NAME, GetVar(object, NAME));
  204.     SetVar(retVal, REPCLASSID, GetVar(object, CLASSID));
  205.  
  206.     return retVal;
  207. }
  208.  
  209. #ifdef PROTO
  210. Bool EqualSnapshots(ObjPtr snap1, ObjPtr snap2)
  211. #else
  212. Bool EqualSnapshots(snap1, snap2)
  213. ObjPtr snap1, snap2;
  214. #endif
  215. /*Returns true iff the two snapshots are equal.  BUGS--assumes that snapvars
  216.   are equal, so only use this on something like a track control where the 
  217.   var group is constant*/
  218. {
  219.     ObjPtr var1, var2;
  220.     ThingListPtr runner;
  221.  
  222.     var1 = GetVar(snap1, REPOBJ);
  223.     var2 = GetVar(snap2, REPOBJ);
  224.     if (var1 != var2) return false;
  225.  
  226.     var1 = GetVar(snap1, SNAPVARS);
  227.     if (var1)
  228.     {
  229.     for (runner = LISTOF(var1); runner; runner = runner -> next)
  230.     {
  231.         var1 = GetVar(snap1, GetSymbolID(runner -> thing));
  232.         var2 = GetVar(snap2, GetSymbolID(runner -> thing));
  233.         if (!Equal(var1, var2)) return false;
  234.     }
  235.     }
  236.  
  237.     return true;
  238. }
  239.  
  240. #ifdef PROTO
  241. void PullSnapVars(ObjPtr newObject, ObjPtr oldObject)
  242. #else
  243. void TakeSnapshot(newObject, oldObject)
  244. ObjPtr newObject, oldObject;
  245. #endif
  246. /*Transters the snap vars of newObject from corresponding values in oldObject*/
  247. {
  248.     ObjPtr list;
  249.     ObjPtr retVal;
  250.  
  251.     /*Make the snap vars*/
  252.     list = AssembleSnapVars(newObject);
  253.  
  254.     if (list)
  255.     {
  256.     ThingListPtr runner;
  257.  
  258.     runner = LISTOF(list);
  259.     while (runner)
  260.     {
  261.         NameTyp id;
  262.  
  263.         id = GetSymbolID(runner -> thing);
  264.         if (id)
  265.         {
  266.         SetVar(newObject, id, GetVar(oldObject, id));
  267.         }
  268.         runner = runner -> next;
  269.     }
  270.     }
  271. }
  272.  
  273. #ifdef PROTO
  274. void ApplySnapshotTo(ObjPtr snapshot, ObjPtr object)
  275. #else
  276. void ApplySnapshotTp(snapshot, object)
  277. ObjPtr snapshot;
  278. ObjPtr object;
  279. #endif
  280. /*Applies snapshot to an object*/
  281. {
  282.     ObjPtr list;
  283.  
  284.     list = GetVar(snapshot, SNAPVARS);
  285.  
  286.     if (list && object)
  287.     {
  288.     ThingListPtr runner;
  289.     ObjPtr value;
  290.  
  291.     runner = LISTOF(list);
  292.     while (runner)
  293.     {
  294.         NameTyp id;
  295.  
  296.         id = GetSymbolID(runner -> thing);
  297.         if (id)
  298.         {
  299.         if (id == VALUE)
  300.         {
  301.             value = GetVar(snapshot, VALUE);
  302.             SetValue(object, value);
  303.         }
  304.         else
  305.         {
  306.             SetVar(object, id, GetVar(snapshot, id));
  307.         }
  308.         }
  309.         runner = runner -> next;
  310.     }
  311.     ImInvalid(object);
  312.     }
  313. }
  314.  
  315. #ifdef PROTO
  316. void ApplySnapshot(ObjPtr snapshot)
  317. #else
  318. void ApplySnapshot(snapshot)
  319. ObjPtr snapshot;
  320. #endif
  321. /*Applies snapshot to its object*/
  322. {
  323.     ObjPtr object;
  324.  
  325.     object = GetVar(snapshot, REPOBJ);
  326.     ApplySnapshotTo(snapshot, object);
  327. }
  328.  
  329. #ifdef PROTO
  330. ObjPtr InterpSimpleObjects(ObjPtr var1, ObjPtr var2, real weight)
  331. #else
  332. ObjPtr InterpSimpleObjects(var1, var2, weight)
  333. ObjPtr var1, var2;
  334. real weight;
  335. #endif
  336. /*Interpolates between two simple objects according to weight.  0 means
  337.   all var1, and 1 means all var2.  If it can't interpolate, prints out
  338.   an error message and does a weighted choice.*/
  339. {
  340.     if (IsInt(var1) && IsInt(var2))
  341.     {
  342.     /*Interpolation of integers*/
  343.     real r1, r2;
  344.  
  345.     r1 = (real) GetInt(var1);
  346.     r2 = (real) GetInt(var2);
  347.  
  348.     return NewInt((int) floor(r2 * weight + r1 * (1.0 - weight) + 0.5));
  349.     }
  350.     else if ((IsReal(var1) || IsInt(var1)) && (IsReal(var2) || IsInt(var2)))
  351.     {
  352.     /*Interpolation of real numbers*/
  353.     real r1, r2;
  354.  
  355.     r1 = GetReal(var1);
  356.     r2 = GetReal(var2);
  357.  
  358.     return NewReal(r2 * weight + r1 * (1.0 - weight));
  359.     }
  360.     else if (IsString(var1) && IsString(var2))
  361.     {
  362.     /*Interpolation of strings.*/
  363.     return (weight >= 0.5) ? var2 : var1;
  364.     }
  365.     else if (IsRealArray(var1) && IsRealArray(var2))
  366.     {
  367.     /*Interpolation of real arrays*/
  368.     long k;
  369.     long length;
  370.     real *el1, *el2, *el3;
  371.     ObjPtr retVal;
  372.  
  373.     /*Make sure that the dimensions are the same*/
  374.     if (RANK(var1) != RANK(var2))
  375.     {
  376.         ReportError("InterpSimpleObjects", "Array rank mismatch");
  377.         return (weight >= 0.5) ? var2 : var1;
  378.     }
  379.  
  380.     length = 1;
  381.     for (k = 0; k < RANK(var1); ++k)
  382.     {
  383.         if (DIMS(var1)[k] != DIMS(var2)[k])
  384.         {
  385.         ReportError("InterpSimpleObjects", "Array dimension mismatch");
  386.         return (weight >= 0.5) ? var2 : var1;
  387.         }
  388.         length *= DIMS(var1)[k];
  389.     }
  390.     el1 = ELEMENTS(var1);
  391.     el2 = ELEMENTS(var2);
  392.  
  393.     retVal = NewArray(AT_REAL, RANK(var1), DIMS(var1));
  394.     if (!retVal)
  395.     {
  396.         return (weight >= 0.5) ? var2 : var1;
  397.     }
  398.  
  399.     el3 = ELEMENTS(retVal);
  400.  
  401.     for (k = 0; k < length; ++k)
  402.     {
  403.         if (el1[k] == missingData || el1[k] == plusInf || el1[k] == minusInf ||
  404.         el2[k] == missingData || el2[k] == plusInf || el2[k] == minusInf)
  405.         {
  406.         el3[k] = (weight >= 0.5) ? el2[k] : el1[k];
  407.         }
  408.         else
  409.         {
  410.         el3[k] = weight * el2[k] + (1.0 - weight) * el1[k];
  411.         }
  412.     }
  413.     return retVal;
  414.     }
  415.     else if (IsObject(var1) && IsObject(var2))
  416.     {
  417.     /*Just two objects*/
  418.     return (weight >= 0.5) ? var2 : var1;
  419.     }
  420.     else
  421.     {
  422.     char errmes[256];
  423.     sprintf(errmes, "Cannot interpolate between values %x and %x\n", var1, var2);
  424.     ReportError("InterpSimpleObjects", errmes);
  425.     return (weight >= 0.5) ? var2 : var1;
  426.     }
  427. }
  428.  
  429. #ifdef PROTO
  430. ObjPtr InterpSnapshots(ObjPtr snap1, ObjPtr snap2, real weight)
  431. #else
  432. ObjPtr InterpSnapshots(snap1, snap2, weight)
  433. ObjPtr snap1, snap2;
  434. real weight;
  435. #endif
  436. /*Returns a weighted interpolation of two snapshots.  Assumes that they have
  437.   the same variables.*/
  438. {
  439.     ObjPtr variables;
  440.     ObjPtr var1, var2;
  441.     ObjPtr retVal;
  442.     ThingListPtr runner;
  443.  
  444.     retVal = NewObject(snapshotClass, 0L);
  445.  
  446.     /*Make the snap vars*/
  447.     variables = GetListVar("InterpSnapshots", snap1, SNAPVARS);
  448.     if (!variables) return ObjFalse;
  449.     SetVar(retVal, SNAPVARS, CopyList(variables));
  450.  
  451.     SetVar(retVal, REPOBJ, GetVar(snap1, REPOBJ));
  452.     SetVar(retVal, NAME, GetVar(snap1, NAME));
  453.     SetVar(retVal, REPCLASSID, GetVar(snap1, CLASSID));
  454.  
  455.     /*Interpolate the variables*/
  456.     runner = LISTOF(variables);
  457.     while (runner)
  458.     {
  459.     NameTyp id;
  460.  
  461.     id = GetSymbolID(runner -> thing);
  462.     var1 = GetVar(snap1, id);
  463.     var2 = GetVar(snap2, id);
  464.     SetVar(retVal, id, InterpSimpleObjects(var1, var2, weight));
  465.  
  466.     runner = runner -> next;
  467.     }
  468.     return retVal;
  469. }
  470.  
  471. #ifdef PROTO
  472. void LogSnapshot(ObjPtr object)
  473. #else
  474. void LogSnapshot(object)
  475. ObjPtr object;
  476. #endif
  477. /*Logs a snapshot of object*/
  478. {
  479.     ObjPtr list;
  480.     ObjPtr retVal;
  481.     Bool needsWindow = false;
  482.  
  483.     needsWindow = MakeObjectName(tempStr, object);
  484.  
  485.     if (needsWindow)
  486.     {
  487.     Log("begin snapshot ");
  488.     Log(tempStr);
  489.     Log("\n");
  490.     }
  491.     else
  492.     {
  493.     LogNoWindow("begin snapshot ");
  494.     LogNoWindow(tempStr);
  495.     LogNoWindow("\n");
  496.     }
  497.  
  498.     /*Make the snap vars*/
  499.     list = AssembleSnapVars(object);
  500.  
  501.     if (list)
  502.     {
  503.     ThingListPtr runner;
  504.     char cmd[256];
  505.     char *s;
  506.  
  507.     runner = LISTOF(list);
  508.     while (runner)
  509.     {
  510.         NameTyp id;
  511.         ObjPtr value;
  512.  
  513.         id = GetSymbolID(runner -> thing);
  514.         if (id)
  515.         {
  516.         value = GetVar(object, id);
  517.         if (IsInt(value))
  518.         {
  519.             sprintf(cmd, "    set variable %s (int) ", GetInternalString(id));
  520.         }
  521.         else
  522.         {
  523.             sprintf(cmd, "    set variable %s ", GetInternalString(id));
  524.         }
  525.         s = &(cmd[0]);
  526.         while (*s) ++s;
  527.         PrintScriptObject(s, value);
  528.         while (*s) ++s;
  529.         *s++ = '\n';
  530.         *s = 0;
  531.         if (needsWindow)
  532.         {
  533.             Log(cmd);
  534.         }
  535.         else
  536.         {
  537.             LogNoWindow(cmd);
  538.         }
  539.         }
  540.         runner = runner -> next;
  541.     }
  542.     }
  543.     if (needsWindow)
  544.     {
  545.     Log("end snapshot\n");
  546.     }
  547.     else
  548.     {
  549.     LogNoWindow("end snapshot\n");
  550.     }
  551. }
  552.  
  553. #ifdef PROTO
  554. void SubsumeObjIntoDatabase(ObjPtr object)
  555. #else
  556. void SubsumeObjIntoDatabase(object)
  557. ObjPtr object;
  558. #endif
  559. /*Subsumes an object into the database.  This means---
  560.   1) Looks for an object with the same name and CLASS_ID
  561.   2) If found,
  562.     Replaces the object in the database with this object, but takes a
  563.     snapshot of the old object from the new object's snapvars and 
  564.     applies it to the new object.
  565.   3) If not found, just adds this object to the database.
  566. */
  567. {
  568.     ObjPtr keyList;
  569.     ObjPtr resultList;
  570.  
  571.     keyList = NewList();
  572.     PostfixList(keyList, NewSymbol(NAME));
  573.     MakeVar(object, NAME);
  574.     PostfixList(keyList, GetVar(object, NAME));
  575.     PostfixList(keyList, NewSymbol(CLASSID));
  576.     MakeVar(object, CLASSID);
  577.     PostfixList(keyList, GetVar(object, CLASSID));
  578.     if (resultList = SearchDatabase(keyList))
  579.     {
  580.     if (LISTOF(resultList))
  581.     {
  582.         PullSnapVars(object, LISTOF(resultList) -> thing);
  583.         DeleteObjFromDatabase(LISTOF(resultList) -> thing);
  584.     }
  585.     }
  586.     AddObjToDatabase(object);
  587. }
  588.  
  589. #ifdef PROTO
  590. void ApplySavedSettings(ObjPtr object)
  591. #else
  592. void ApplySavedSettings(object)
  593. ObjPtr object;
  594. #endif
  595. /*Applies the saved settings to object*/
  596. {
  597.     ObjPtr directory;
  598.  
  599.     directory = GetSettingsDirectory();
  600.  
  601.     ReadObjectControls(object, directory, false);
  602. }
  603.  
  604. #ifdef PROTO
  605. ObjPtr GetSettingsDirectory(void)
  606. #else
  607. ObjPtr GetSettingsDirectory()
  608. #endif
  609. /*Returns a string of the settings directory, which by default is
  610.   ~/scianSettings.  Creates the directory if need be*/
  611. {
  612.     char dirName[256];
  613.     struct stat buf;
  614.     int notThere;
  615.  
  616.     sprintf(dirName, "%s/%s", getenv("HOME"), ".scianSettings");
  617.     notThere = stat(dirName, &buf);
  618.     if (notThere)
  619.     {
  620.     FILE *outFile;
  621.  
  622.     /*Have to create it*/
  623.     if (mkdir(dirName, S_IREAD | S_IWRITE | S_IEXEC))
  624.     {
  625.         /*Failed to create*/
  626.         ReportError("GetSettingsDirectory", "Cannot create directory");
  627.         return NULLOBJ;
  628.     }
  629.     notThere = stat(dirName, &buf);
  630.     if (notThere)
  631.     {
  632.         /*Still not there, return null*/
  633.         ReportError("GetSettingsDirectory", "Tried create directory, but it's not there");
  634.         return NULLOBJ;
  635.     }
  636.  
  637.     /*Put in a README*/
  638.     strcpy(tempStr, dirName);
  639.     strcat(tempStr, "/README");
  640.     outFile = fopen(tempStr, "w");
  641.     if (!outFile)
  642.     {
  643.         ReportError("GetSettingsDirectory", "Cannot create files in directory");
  644.         return NULLOBJ;
  645.     }
  646.     fprintf(outFile, "This directory is used to save settings from within SciAn.\n");
  647.     fclose(outFile);
  648.     }
  649.  
  650.     /*Directory exists, see if it's OK*/
  651.     if ((buf.st_mode & S_IFMT) == S_IFDIR)
  652.     {
  653.     /*It's OK*/
  654.     return NewString(dirName);
  655.     }
  656.     ReportError("GetSettingsDirectory", "Problem using settings directory");
  657.     return NULLOBJ;
  658. }
  659.  
  660. ObjPtr SaveSnapshotControls(object)
  661. ObjPtr object;
  662. /*Saves an object's controls from a snapshot*/
  663. {
  664.     ObjPtr directory;
  665.  
  666.     directory = GetSettingsDirectory();
  667.  
  668.     SaveObjectControls(object, directory);
  669.     return ObjTrue;
  670. }
  671.  
  672. ObjPtr LogSnapshotControls(object)
  673. ObjPtr object;
  674. /*Logs all the controls for an object*/
  675. {
  676.     LogSnapshot(object);
  677.     return ObjTrue;
  678. }
  679.  
  680. #ifdef PROTO
  681. void InitSnapshots(void)
  682. #else
  683. void InitSnapshots()
  684. #endif
  685. /*Initializes snapshot system*/
  686. {
  687.     snapshotClass = NewObject(NULLOBJ, 0L);
  688.     AddToReferenceList(snapshotClass);
  689.     SetVar(snapshotClass, CLASSID, NewInt(CLASS_SNAPSHOT));
  690.     classClasses[CLASS_SNAPSHOT] = snapshotClass;
  691. }
  692.  
  693. #ifdef PROTO
  694. void KillSnapshots(void)
  695. #else
  696. void KillSnapshots()
  697. #endif
  698. /*Kills the snapshot system*/
  699. {
  700.     RemoveFromReferenceList(snapshotClass);
  701. }
  702.  
  703.